/**********************************************************************
 *
 * This code is developed for the course Informatica Industrial II
 * of Universidad Carlos III de Madrid - 2012
 * Authors: Victor González-Pacheco, Alberto Valero-Gomez
 *
 * The code is licenced under the Common Creative License,
 * Attribution-ShareAlike 3.0
 *
 * You are free:
 *   - to Share - to copy, distribute and transmit the work
 *   - to Remix - to adapt the work
 *
 * Under the following conditions:
 *   - Attribution. You must attribute the work in the manner specified
 *     by the author or licensor (but not in any way that suggests that
 *     they endorse you or your use of the work).
 *   - Share Alike. If you alter, transform, or build upon this work,
 *     you may distribute the resulting work only under the same or
 *     similar license to this one.
 *
 * Any of the above conditions can be waived if you get permission
 * from the copyright holder.  Nothing in this license impairs or
 * restricts the author's moral rights.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.
 **********************************************************************/


#ifndef TCPSOCKETSERVER__H
#define TCPSOCKETSERVER__H



#include "TCPSocket.h"
#include <vector>

using namespace std;

/**
  * \brief TCP Socket Server Class
  * This class implements a TCP Socket Server using the paradigm os streams
  */
class TCPSocketServer{

public:
    /**
      * \brief Parametrized Constructor
      * \param ip local IP Address (by default localhost)
      * \param port local port (by default assinged by function bind)
      * \param max_connections Max accepted incoming connections
      * \throw string if it cannot open or connect the socket
      */
    TCPSocketServer(int port, int max_connections=10, string ip="192.168.0.30") throw(char const *);

    ~TCPSocketServer(){
        try{
            _incoming_socket->close();
            for (int i=0;i<connections.size();i++){
                connections[i].close();
            }
        }catch(char const* e){
            cout << e;
        }
    }

    /**
      * \brief Binds the Socket for incoming connections
      * Binds the Socket to the preset IP/Server Name and Port for incoming connections
      * \throw string if socket cannot be binded
      * \return true is sockes has been binded
      */
    bool bind() throw(char const *);

    /**
      * \brief Listens on a binded Socket for incoming connections
      * \throw string if socket cannot listen
      * \return the result of the listen operation
      */
    int listen() throw(char const *);

    /**
     * @brief accept incoming connections
     * @return id of the connection (in the vector of TCPSockets)
     */
    int accept() throw(char const *);


    /**
      * \brief Return true if socket is binded
      * \return True if socket is binded
      */
    inline bool isBinded(){ return _binded; }
    /**
      * \brief Return true if socket is listening
      * \return True if socket is listening
      */
    inline bool isListening(){ return _listening; }


    vector<TCPSocket> connections;

protected:

    TCPSocket* _incoming_socket;
    bool _binded; //!< Socket is binded
    bool _listening; //!< Socket is listening
    int _max_connections; //!< Max incoming connections. By default 10

};


#endif //TCPSOCKETSERVER__H
